import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { laravel } from '@na/vite'
import type { ConfigEnv, PluginOption, ViteDevServer } from '@na/vite'

let exitHandlersBound = false
const publicDirectory = 'E:/phpEnv/www/laravel-admin/public'

const refreshPaths = [
  'E:/phpEnv/www/laravel-admin/app/Livewire/**',
  'E:/phpEnv/www/laravel-admin/app/View/Components/**',
  'E:/phpEnv/www/laravel-admin/lang/**',
  'E:/phpEnv/www/laravel-admin/resources/lang/**',
  'E:/phpEnv/www/laravel-admin/resources/views/**',
  'E:/phpEnv/www/laravel-admin/routes/**',
].filter((path: string) => fs.existsSync(path.replace(/\*\*$/, '')))

export function setupLaravel(env: ConfigEnv): PluginOption {
  const isServe = env.command === 'serve'
  const config = {
    input: ['src/main.ts'],
    publicDirectory: 'public',
    buildDirectory: 'build',
    refresh: true,
  }
  if (isServe) {
    config.publicDirectory = publicDirectory
    // @ts-ignore
    config.refresh = [{ paths: refreshPaths }]
  }
  const la = laravel(config)
  if (isServe) {
    la[0].configureServer = (server: ViteDevServer) => {
      const hmr = server.config.server.hmr
      const host = server.config.server.host
      const https = server.config.server.https
      const hostFile = path.join(config.publicDirectory, 'hot')
      server.httpServer?.once('listening', () => {
        const address: any = server.httpServer?.address()
        const isAddressInfo = (x: any) => typeof x === 'object'
        if (isAddressInfo(address)) {
          const configHmrProtocol = typeof hmr === 'object' ? hmr.protocol : null
          const clientProtocol = configHmrProtocol ? (configHmrProtocol === 'wss' ? 'https' : 'http') : null
          const serverProtocol = https ? 'https' : 'http'
          const protocol = clientProtocol ?? serverProtocol
          const configHmrClientPort = typeof hmr === 'object' ? hmr.clientPort : null
          const port = configHmrClientPort ?? address.port
          const localhost = host ?? address.host
          const viteDevServerUrl = `${protocol}://${localhost}:${port}`
          fs.writeFileSync(hostFile, `${viteDevServerUrl}${server.config.base.replace(/\/$/, '')}`)
        }
      })

      if (!exitHandlersBound) {
        const clean = () => {
          if (fs.existsSync(hostFile)) {
            fs.rmSync(hostFile)
          }
        }

        process.on('exit', clean)
        process.on('SIGINT', () => process.exit())
        process.on('SIGTERM', () => process.exit())
        process.on('SIGHUP', () => process.exit())

        exitHandlersBound = true
      }
    }
  }

  return la
}
